﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using DDOS.Objects.Projectiles;
using DDOS.Camera;

namespace DDOS.Objects
{
    class Minion : Entity
    {
        private const Decimal SPEED = 5m;
        private Vector2 origin;
        int frame;
        int time;
        private Vector2 patrol_point;
        private bool on_patrol;
        Random ran;
        Rectangle spriteRectangle, sourceRectangle1, sourceRectangle2, sourceRectangle3;
        public List<Projectile0> bullets;
        public int shootDelay = 2000;
        public string Name;

        Gambit curGambit;
        int curGambitDepth;
        BoundingObject curGambitTarget;

        private BoundingCircle bounding_circle;
        public BoundingCircle boundingCircle
        {
            get { return bounding_circle; }
            set { bounding_circle = value; bounding_circle.parent = this; }
        }

        public void init_camera(Camera3D cam)
        {
            this.camera = cam;
        }

        public Minion(string n)
        {
            Name = n;
        }

        public override void InitializeComponents()
        {
            bullets = new List<Projectile0>();
            gambits = new List<Gambit>();
            gambits.Add(new LongAttackGambit(Gambit.NearestEnemy));
            curGambit = null;
            curGambitTarget = null;
            curGambitDepth = 1000;
            this.maxHealth = 4;
            this.health = 4;
            this.power = 2;
            this.speed = 3;
            this.sight = 100; 
            this.frame = ran.Next(0,2);
            if (frame == 0)
            {
                time = 0;
            }
            if (frame == 1)
            {
                time = 3;
            }
            if (frame == 2)
            {
                time = 6;
            }
            on_patrol = true;
            this.patrol_point = new Vector2(origin.X + ran.Next(-75, 75), origin.Y + ran.Next(-75, 75));
            this.texture = ImageManager2D.Instance.Minion;

            if (coordinates == null)
                InitialCoordinates(0, 0);

            boundingObject = new BoundingRectangle((int)coordinates.X, (int)coordinates.Y, (int)coordinates.X + 25, (int)coordinates.Y + 25);
            boundingCircle = new BoundingCircle(coordinates.X, coordinates.Y, (float)this.sight);

            spriteRectangle = new Rectangle((int)coordinates.X, (int)coordinates.Y, 25, 25);
            sourceRectangle1 = new Rectangle(0,0,27,28);
            sourceRectangle2 = new Rectangle(30, 0, 27, 28);
            sourceRectangle3 = new Rectangle(60, 0, 27, 28);
            this.velocity = new Vector2(0, 0);
            blocked = false;
        }

        public override void CollisionCallback(BoundingObject other, BoundingObject self)
        {
            Type otherType = other.parent.GetType();
            #region Check Agro Circle
            if (self == boundingCircle && typeof(Entity).IsAssignableFrom(otherType))
            {
                for(int i=0; i<gambits.Count && i<=curGambitDepth; i++)
                {
                    Gambit g = gambits[i];
                    if (g.CheckCondition(self.parent, other.parent)>0)
                    {
                        if (i == curGambitDepth)
                        {
                            if (g.CheckCondition(self.parent, other.parent) > curGambit.CheckCondition(self.parent, curGambitTarget.parent))
                            {
                                curGambit = g;
                                curGambitDepth = i;
                                curGambitTarget = other;
                            }
                        }
                        else
                        {
                            curGambit = g;
                            curGambitDepth = i;
                            curGambitTarget = other;
                        }
                        break;
                    }
                }
            }
            #endregion
            else if (self == boundingObject)
            {
                if (other.parent.GetType() == typeof(Projectile0))
                {
                    Projectile0 p = (Projectile0)other.parent;
                    if (p.source.GetType() == typeof(Minion) && p.damage < 0 && p.source!=this)
                    {
                        health -= p.damage;
                        if (health > maxHealth)
                            health = maxHealth;
                    }
                    else if (p.source.GetType() == typeof(Enemy0))
                    {
                        health -= p.damage;
                    }
                }
                else if (other.parent.GetType() == typeof(Enemy0) && other == other.parent.boundingObject)
                {
                    Enemy0 e = (Enemy0)other.parent;
                    e.Health -= power;
                    health -= e.Power;
                }
            }
        }

        public void init_random(Random r)
        {
            ran = r;
        }

        private void patrol()
        {

            if ((this.coordinates - patrol_point).Length() >= (float)/*SPEED*/speed)
            {
                Vector2 v = (patrol_point - this.coordinates);
                v.Normalize();
                velocity = v * (float)speed;
                //coordinates += v*(float)speed;
            }
            else
            {
                this.patrol_point = new Vector2(origin.X + ran.Next(-75, 75), origin.Y + ran.Next(-75, 75));
            }

        }

        private void input()
        {
            Vector2 right = InputManager.InputManagerInstance.GetGamePadThumbstickState(InputManager.GamePadThumbstick.right);
            this.velocity = Vector2.Zero;

            if (right != Vector2.Zero)
            {
                /*on_patrol = false;
                if (!blocked)
                {
                    if ((this.coordinates.X < this.origin.X + 125) && (this.coordinates.X > this.origin.X - 125) && (this.coordinates.Y < this.origin.Y + 125) && (this.coordinates.Y > this.origin.Y - 125))
                    {
                        this.velocity.X += right.X * (float)SPEED;
                        this.velocity.Y += right.Y * (float)SPEED;
                    }
                    else
                    {
                        on_patrol = true;
                    }
                }
                else
                {
                    this.velocity.X = 0;
                    this.velocity.Y = 0;
                }*/
            }
            else
            {
                on_patrol = true;
            }
        }

        private void act()
        {
           if (curGambit != null)
            {
                curGambit.Activate(this, curGambitTarget.parent);
            }
            curGambit = null;
            curGambitTarget = null;
            curGambitDepth = 1000;
        }

        public void pass_origin(Vector2 o)
        {
            this.origin = o;
        }

        public override void Update(GameTime game_time)
        {
            if (shootDelay > 0)
                shootDelay -= game_time.ElapsedGameTime.Milliseconds;

            if(bullets!=null)
                for (int i = bullets.Count - 1; i >= 0; i--)
                {
                    if (bullets[i].deleteMe)
                    {
                        CollisionEngine.Instance.Remove(bullets[i].boundingObject);
                        bullets.RemoveAt(i);
                    }
                    else
                        bullets[i].Update(game_time);
                }

            input();
            if (curGambit == null || InputManager.InputManagerInstance.GetGamePadThumbstickState(InputManager.GamePadThumbstick.right) != Vector2.Zero)
            {
                patrol();
            }
            else
            {
                act();
            }
            time += 1;
            this.coordinates += this.velocity;
            this.boundingObject.Move(this.velocity.X, this.velocity.Y);
            this.boundingCircle.Move(this.velocity.X, this.velocity.Y);
            this.spriteRectangle.X = (int)this.coordinates.X;
            this.spriteRectangle.Y = (int)this.coordinates.Y;
        }
        public override void Draw()
        {
            if (bullets != null)
                foreach (Projectile0 p in bullets)
                    p.Draw();

            if (time <= 3)
            {
                ScreenManager.Instance.CurrentSpriteBatch.Draw(texture, spriteRectangle, sourceRectangle1, Color.White);
            }
            else if (time <= 6)
            {
                ScreenManager.Instance.CurrentSpriteBatch.Draw(texture, spriteRectangle, sourceRectangle2, Color.White);
            }
            else if (time <= 9)
            {
                ScreenManager.Instance.CurrentSpriteBatch.Draw(texture, spriteRectangle, sourceRectangle3, Color.White);
            }
            else
            {
                ScreenManager.Instance.CurrentSpriteBatch.Draw(texture, spriteRectangle, sourceRectangle1, Color.White);
                time = 0;
            }
        }

    }
}
